 package model;

import java.util.*;
import java.awt.*;

import javax.swing.JOptionPane;

public class Player{
   
	private String name, password;
	private Color color;
	private TechnologyLevel level;
    private int food;
    private int technology;
    
    private ArrayList<Territory> territoryList;
    private ArrayList<Spy> spyList;
    private ArrayList<Player> allyList;
    private ArrayList<Player> enemyList;
     
    //constructor
    public Player(String name , String password, Color color){
        this.name = name;
        this.password = password;
        level = TechnologyLevel.Infantry;
        technology = 0;
        food = 0;
        this.color = color;
        territoryList = new ArrayList<Territory>();
        spyList = new ArrayList<Spy>();
        allyList = new ArrayList<Player>();
        enemyList = new ArrayList<Player>();
        if (name == "Tester")
        	technology = 1000;
            food = 1000;
     } 
    public Player(String name, Color color){ // for enemy
    	this.name = name;
    	this.color = color;
    	level = TechnologyLevel.Infantry;
        technology = 0;
        food = 0;
        territoryList = new ArrayList<Territory>();
        spyList = new ArrayList<Spy>();
        allyList = new ArrayList<Player>();
        enemyList = new ArrayList<Player>();
    }
    
    //getter and setter
    public String getPassword(){return password;}
    public void setLevel(TechnologyLevel level){this.level = level;}
    public ArrayList<Spy> getSpyList(){return spyList;}
    public ArrayList<Player> getAllyList(){return allyList;}
    public ArrayList<Player> getEnemyList(){return enemyList;}
    public void addEnemy(Player enemy){enemyList.add(enemy);}
    public int getSpyAmount(){return spyList.size();}
    public ArrayList<Territory> getTerritoryList(){return territoryList;}
    public int getFood(){return food;}
    public int getTechnology(){return technology;}
    public TechnologyLevel getLevel(){return level;}
    public int getTerritoryAmount(){return territoryList.size();}
    public Color getColor(){return color;}
    public String getName(){return name;}
    
    public int getFoodUnit(){
    	int foodUnit = 0;
    	for (Territory t : territoryList)
    		foodUnit += t.getFoodUnit();
    	return foodUnit;
    }
    public int getTechnologyUnit(){
    	int technologyUnit = 0;
    	for (Territory t: territoryList)
    		technologyUnit += t.getTechnologyUnit();
    	return technologyUnit;
    }
    public int getTroopAmount(){
    	int TroopAmount = 0;
    	for (Territory t: territoryList)
    		TroopAmount += t.getTroopAmount(this);
    	for (Player p : allyList)
    		for (Territory t: p.getTerritoryList())
    		   TroopAmount += t.getTroopAmount(this);
    	return TroopAmount;
    }
    public int getTroopAmount(TechnologyLevel level){
    	int TroopAmount = 0;
    	for (Territory t: territoryList)
    		TroopAmount += t.getTroopAmount(level, this);
    	for (Player p : allyList)
    		for (Territory t: p.getTerritoryList())
    		   TroopAmount += t.getTroopAmount(level, this);
    	return TroopAmount;
    }
    //other methods
    public void updateTerritory(Territory t){
    	if (territoryList.contains(t))
    			territoryList.remove(t);
    		else territoryList.add(t);
    }  
  
    public boolean hasSpy(Territory territory){
    	for (Spy spy: spyList)
    		if (spy.getTerritory() == territory) return true; 
        return false;
    }
    public boolean isAlly(Player player){
    	if (allyList.contains(player))
    		 return true;
    	return false;
    }
    public void addSpy(Spy spy){spyList.add(spy);}
    public void removeSpy(Spy spy){spyList.remove(spy);}
    public void formAlliance(Player player){allyList.add(player);}
    public void breakAlliance(Player player){allyList.remove(player);}
    public void cutTechnology(int n){technology -= n;}
    public void addTechnology(int n){technology += n;}
    public void upgradeLevel(){level = level.Next();}
    public void downgradeLevel(){level = level.Previous();}
  
    public void feed(){
    	food += getFoodUnit();
    	technology += getTechnologyUnit();
    	if (food >= getTroopAmount() + getTerritoryAmount()) {
    		food -= getTroopAmount() + getTerritoryAmount();
    		for (Territory t: territoryList)
    			t.addTroop(new Troop(TechnologyLevel.Infantry, this));
    		return;
        }// enough food for all the troops, every territory can get one new infantry
    	if (food >= getTroopAmount()){
    		food -= getTroopAmount();
    		return;
    	}// enough food for all the troops, no new infantry
    	int diff = getTroopAmount() - food;// no enough food, diff troops must die
    	while (diff > 0){
    	    int n = 0;
    	    TechnologyLevel level = TechnologyLevel.Infantry;
    	    while (getTroopAmount(level) == 0)//no troops for this type
    	       level = level.Next();//check next type
    	       if (level == null)
    	    	   return;
    	    do {
    		   n = (int)Math.random() * getTerritoryAmount();
    	    }while (territoryList.get(n).getTroopAmount(level, this) == 0);// random choose a territory if it has specific type of troop 
    	    JOptionPane.showMessageDialog(null, territoryList.get(n).getLocation() + "One of your " + level + " starved to death!");
    	    territoryList.get(n).removeTroop(level, this);// remove one troop
            diff --;
    	}
    }
}
    	
    	   

